/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* includes (local) ----------------------------------------------------------*/
#include <hal_rtc.h>
/* includes (standard library, system) ---------------------------------------*/
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/

/* defines -------------------------------------------------------------------*/
/* typedefs ------------------------------------------------------------------*/
/* macro ---------------------------------------------------------------------*/
/* variables (extern) --------------------------------------------------------*/
/* variables (local) ---------------------------------------------------------*/
/* variables (global) --------------------------------------------------------*/
/* inlines -------------------------------------------------------------------*/
/* functions -----------------------------------------------------------------*/

hal_rtc_t *hal_rtc_open(const char *name)
{
    return container_of(hal_open(name, 0), hal_rtc_t, parent);
}

int hal_rtc_close(hal_rtc_t *rtc)
{
    return hal_close((hal_dev_t *)rtc);
}

int hal_rtc_set_time(hal_rtc_t *rtc, const hal_rtc_time_t *time)
{
    if (rtc == NULL || time == NULL) {
        return -EINVAL;
    }
    if (rtc->methods->set_time == NULL) {
        return -ENOSYS;
    }
    return rtc->methods->set_time(rtc, time);
}

int hal_rtc_get_time(hal_rtc_t *rtc, hal_rtc_time_t *time)
{
    if (rtc == NULL || time == NULL) {
        return -EINVAL;
    }
    if (rtc->methods->get_time == NULL) {
        return -ENOSYS;
    }
    return rtc->methods->get_time(rtc, time);
}

int hal_rtc_set_alarm(hal_rtc_t *rtc, const hal_rtc_time_t *alarm_time,
                      hal_rtc_alarm_callback_t callback, uintptr_t arg)
{
    if (rtc == NULL || alarm_time == NULL || callback == NULL) {
        return -EINVAL;
    }
    if (rtc->methods->set_alarm == NULL) {
        return -ENOSYS;
    }
    rtc->alarm_cb = callback;
    rtc->alarm_arg = arg;
    return rtc->methods->set_alarm(rtc, alarm_time);
}

int hal_rtc_disable_alarm(hal_rtc_t *rtc)
{
    if (rtc == NULL) {
        return -EINVAL;
    }
    if (rtc->methods->disable_alarm == NULL) {
        return -ENOSYS;
    }
    return rtc->methods->disable_alarm(rtc);
}

void hal_rtc_alarm_handler(hal_rtc_t *rtc)
{
    if (rtc == NULL) {
        return;
    }
    if (rtc->alarm_cb == NULL) {
        return;
    }
    rtc->alarm_cb(rtc->alarm_arg);
}

int hal_rtc_register(hal_rtc_t *rtc, const char *name, const hal_rtc_methods_t *methods,
                     uintptr_t data)
{
    if (rtc == NULL || methods == NULL) {
        return -EINVAL;
    }
    rtc->parent.name = name;
    rtc->methods = methods;

    if (hal_register(&rtc->parent) != 0) {
        return -1;
    }

    return 0;
}
